package com.docMan.service.impl;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.commons.net.ftp.FTPFile;
import org.apache.lucene.search.TopDocs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.docMan.bean.DeleteDirRunnable;
import com.docMan.bean.DeleteIndexRunnable;
import com.docMan.bean.DirectoryMakeRunnable;
import com.docMan.bean.IndexFile;
import com.docMan.bean.IndexRunnable;
import com.docMan.bean.UpdateDirRunnable;
import com.docMan.bean.UpdateDiskRunnable;
import com.docMan.dao.BaseDao;
import com.docMan.dao.pojo.DocDirectory;
import com.docMan.dao.pojo.DocDirectoryRange;
import com.docMan.dao.pojo.DocDirectoryRangeId;
import com.docMan.dao.pojo.DocDisc;
import com.docMan.dao.pojo.DocFile;
import com.docMan.dao.pojo.Tchuman;
import com.docMan.lucene.Indexer;
import com.docMan.lucene.Searcher;
import com.docMan.service.DocDirectoryRangeService;
import com.docMan.service.DocDirectoryService;
import com.docMan.service.DocDiscService;
import com.docMan.service.DocFileService;
import com.docMan.service.TchumanService;
import com.docMan.service.TcunitService;
import com.docMan.utils.CastUtil;
import com.docMan.utils.FileIndexService;
import com.docMan.utils.FileMoveService;
import com.docMan.utils.FinalConfig;
import com.docMan.utils.FtpUtils;
import com.docMan.utils.GetRealPath;
import com.docMan.utils.ProjectUtils;
import com.docMan.utils.StringUtil;

@Service("docDirectoryService")
public class DocDirectoryServiceImpl extends BaseServiceImpl<DocDirectory>
		implements DocDirectoryService {

	private DocDiscService docDiscService;
	private FileMoveService fileMoveService = FileMoveService.getInstance();
	private DocFileService docFileService;
	private FileIndexService fileIndexService = FileIndexService.getInstance();
	private DocDirectoryRangeService docDirectoryRangeService;
	private HttpSession session;
	private TcunitService tcunitService;
	private TchumanService tchumanService;

	@Resource
	public void setTchumanService(TchumanService tchumanService) {
		this.tchumanService = tchumanService;
	}

	@Resource
	public void setTcunitService(TcunitService tcunitService) {
		this.tcunitService = tcunitService;
	}

	@Autowired
	public void setSession(HttpSession session) {
		this.session = session;
	}

	@Resource
	public void setDocDirectoryRangeService(
			DocDirectoryRangeService docDirectoryRangeService) {
		this.docDirectoryRangeService = docDirectoryRangeService;
	}

	@Resource
	public void setDocFileService(DocFileService docFileService) {
		this.docFileService = docFileService;
	}

	@Resource
	public void setDocDiscService(DocDiscService docDiscService) {
		this.docDiscService = docDiscService;
	}

	@Resource
	@Override
	public void setDao(BaseDao<DocDirectory> dao) {
		// TODO Auto-generated method stub
		super.setDao(dao);
	}
	
	@Override
	public String saveOrUpdateDirectory(DocDirectory docDirectory,
			List<Integer> humanIds) {
		if (CastUtil.castBoolean(session.getAttribute(FinalConfig.canCreatDir))) {
			if (null == docDirectory.getId() || docDirectory.getId() <= 0) {
				docDirectory.setDirectoryCount(0);
				docDirectory.setFileCount(0);
				docDirectory.setHumanId((int) session
						.getAttribute(FinalConfig.SESSION_HUMANID));
				docDirectory.setLarge(0.0);
				docDirectory.setHumanName(session.getAttribute(
						FinalConfig.SESSION_HUMANNAME).toString());
				// TODO 这里需要改成去获取这个文件夹父路径上diskid的unitID
				if (docDirectory.getDiskId() == null) {
					docDirectory.setUnitId(getDirectoryDiskId(docDirectory
							.getDirectoryId()));
				} else {
					DocDisc docdisk = docDiscService.getById(docDirectory
							.getDiskId());
					docDirectory.setUnitId(docdisk.getUnitId());
				}
				docDirectory.setCreateTime(new Timestamp(System
						.currentTimeMillis()));
				docDirectory.setPath(getDirectoryPath(docDirectory));
				// updateDirectoryDirCount(docDirectory);
				save(docDirectory);
				// add(humanIds,docDirectory.getDirectoryId());
				put("directory", docDirectory);
				putSuccess();
				fileMoveService.move(new DirectoryMakeRunnable(
						getFtpDirectoryFullPath(docDirectory),
						FinalConfig.getDocFtp()));
				updateDirWhenAddDir(docDirectory);
				docDirectoryRangeService.saveDirSeeableHuman(
						docDirectory.getId(), docDirectory.getDisplayRange(),
						humanIds);
			} else {
				DocDirectory docDirectoryO = getById(docDirectory.getId());
				if (docDirectoryO.getHumanId() != (int) session
						.getAttribute(FinalConfig.SESSION_HUMANID)) {
					putFalse();
					putMessage("你不是文件的创建者，无法修改文件夹的信息");
					return getMap();
				}
				/*
				 * docDirectoryO.setReName(docDirectory.getReName());
				 * saveOrUpdate(docDirectoryO);
				 */
				excudeSqlUpdate(
						"update doc_directory set doc_directory.displayName=? ,doc_directory.displayRange=? where doc_directory.id=?",
						docDirectory.getReName(),
						docDirectory.getDisplayRange(), docDirectory.getId());
				try {
					updateDirectoryDiplayRange(docDirectory,
							docDirectoryO.getHumanId(), humanIds);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				put("directory", docDirectory);
				putSuccess();
			}
		} else {
			putFalse();
			putMessage("这不是你的个人网盘，你无法在这里执行创建文件夹，上传文件，删除等操作");
		}
		return getMap();
	}

	/**
	 * 对文件夹的权限范围进行跟新
	 * 
	 * @param docDirectory
	 * @param humanIds
	 * @throws IOException
	 */
	private void updateDirectoryDiplayRange(DocDirectory docDirectory,
			int humanid, List<Integer> humanIds) throws IOException {
		docDirectoryRangeService.update(
				"delete from DocDirectoryRange d where d.id.directoryId=?",
				docDirectory.getId());
		if (docDirectory.getDisplayRange().equals(
				FinalConfig.DirectoryDisplayRange_HUMANS)) {
			List<DocDirectoryRange> directoryRanges = new ArrayList<>();
			for (Integer humanId : humanIds) {
				DocDirectoryRange docDirectoryRange = new DocDirectoryRange(
						new DocDirectoryRangeId(docDirectory.getId(), humanId));
				directoryRanges.add(docDirectoryRange);
			}
			directoryRanges.add(new DocDirectoryRange(new DocDirectoryRangeId(
					docDirectory.getId(), humanid)));
			docDirectoryRangeService.saveOrUpdateAll(directoryRanges);
		}
		changeIndexFileSearchAbleWhenDirectoryDisplayChange(docDirectory,
				humanIds);
	}

	/**
	 * 当文件夹的可见范围更改时，同时更改该文件夹下文件的索引的可搜索范围
	 * 
	 * @throws IOException
	 */
	private void changeIndexFileSearchAbleWhenDirectoryDisplayChange(
			DocDirectory docDirectory, List<Integer> humanIds)
			throws IOException {
		Indexer indexer = Indexer.getInstance(FinalConfig.index_dir);
		List<DocFile> docFiles = docFileService.find(
				"select file from DocFile file where file.directoryId=?",
				docDirectory.getId());
		Map<String, String> fields = new HashMap<String, String>();
		fields.put("searchable", docDirectory.getDisplayRange());
		if (docDirectory.getDisplayRange().equals(
				FinalConfig.DirectoryDisplayRange_UNIT)) {
			fields.put("unitId", CastUtil.castString(docDirectory.getUnitId()));
		} else if (docDirectory.getDisplayRange().equals(
				FinalConfig.DirectoryDisplayRange_HUMANS)) {
			if (humanIds.size() > 0) {
				StringBuilder humanIdsBuilder = new StringBuilder();
				for (Integer humanId : humanIds) {
					humanIdsBuilder.append("[" + humanId + "],");
				}
				fields.put("humanIds", humanIdsBuilder.toString());
			}
		}
		for (DocFile docFile : docFiles) {
			indexer.update(docFile.getId().toString(), fields);
		}
	}

	/**
	 * 在创建新的文件夹时，更新所在文件夹的包含的文件夹数
	 * 
	 * @param directoryId
	 */
	@SuppressWarnings("unused")
	private void updateDirectoryDirCount(DocDirectory dir) {
		if (dir.getDirectoryId() != null && dir.getDirectoryId() > 0) {
			DocDirectory docDirectory = getById(dir.getDirectoryId());
			docDirectory
					.setDirectoryCount(docDirectory.getDirectoryCount() + 1);
			update(docDirectory);
		}
	}

	/**
	 * 创建文件夹时 更新文件的父亲（文件夹或者网盘）的文件夹数 并且该操作是线程安全的
	 * 
	 * @param docDirectory
	 */
	private void updateDirWhenAddDir(DocDirectory docDirectory) {
		// TODO 这里还有问题，就是多线程下数据无法保证安全性
		if (null != docDirectory.getDiskId() && docDirectory.getDiskId() > 0) {
			fileIndexService.updateDisk(new UpdateDiskRunnable(docDirectory
					.getDiskId(), 1, 0));
		} else {
			DocDirectory docDir = getById(docDirectory.getDirectoryId());
			docDir.setDirectoryCount(null != docDir.getDirectoryCount() ? docDir
					.getDirectoryCount() + 1 : 1);
			fileIndexService.updateDirectory(new UpdateDirRunnable(docDirectory
					.getDirectoryId(), 0, 1, 0));
		}
	}

	/**
	 * 在创建文件夹时，需要根据当前文件夹所在位置，记录当前路径
	 * 
	 * @param docDirectory
	 * @return
	 */
	private String getDirectoryPath(DocDirectory docDirectory) {
		Integer diskId = docDirectory.getDiskId();
		if (diskId != null) {
			// DocDisc docDisc=docDiscService.getById(diskId);
			return diskId.toString();
		} else {
			DocDirectory directoryParent = getById(docDirectory
					.getDirectoryId());
			return directoryParent.getPath() + "/"
					+ docDirectory.getDirectoryId();
		}
	}

	/**
	 * 新建文件夹时，获取文件夹的完整路径的id，然后创建对应的文件夹
	 * 
	 * @param docDirectory
	 * @return
	 */
	private String getFtpDirectoryFullPath(DocDirectory docDirectory) {
		return docDirectory.getPath() + "/" + docDirectory.getId();
	}

	@SuppressWarnings("unchecked")
	@Override
	public String getDirectory(int directoryId) {
		if (directoryId > 0) {
			DocDirectory docDirectory = getById(directoryId);
			String realPath = GetRealPath.getPath(docDirectory.getPath());
			put("path", realPath);
			put("directory", docDirectory);
			if (docDirectory.getDisplayRange().equals(
					FinalConfig.DirectoryDisplayRange_HUMANS)) {
				List<Integer> humanIds = docDirectoryRangeService
						.sqlQueryNoCache(
								"select doc_directory_range.humanId from doc_directory_range where doc_directory_range.directoryId=?",
								directoryId);
				// humanIds.remove((Integer)session.getAttribute(FinalConfig.SESSION_HUMANID));
				List<Tchuman> tchumans = new ArrayList<>();
				for (Integer integer : humanIds) {
					Tchuman tchuman = tchumanService.getById(integer);
					tchumans.add(tchuman);
				}
				put("tchumans", tchumans);
			}
		}

		return getMap();
	}

	@Override
	public String deleteDirectory(int directoryId) {
		// TODO 删除文件夹时，删除文件夹下文件时要同时删除索引
		DocDirectory docDirectory = getById(directoryId);
		if (docDirectory.getHumanId() != (int) session
				.getAttribute(FinalConfig.SESSION_HUMANID)) {
			putFalse();
			putMessage("你不是文件夹的创建者，没有权限删除文件夹");
			return getMap();
		}
		updateDirectoryWhenDelDir(docDirectory);
		String realPath = GetRealPath.getPath(docDirectory.getPath()) + "/"
				+ docDirectory.getName();
		fileMoveService.move(new DeleteDirRunnable(realPath));
		deleteIndexWhenDelDir(docDirectory);
		update("delete DocDirectory d where d.path like ?",
				docDirectory.getPath() + "/" + docDirectory.getId() + "%");
		docFileService.update("delete DocFile f where f.path like ?",
				docDirectory.getPath() + "/" + docDirectory.getId() + "%");
		delete(docDirectory);
		putSuccess();
		return getMap();
	}

	/**
	 * 在删除文件夹时 同时删除对文件夹下,及文件夹下的文件夹中的文件建立的lucene本地索引
	 * 
	 * @param docDirectory
	 */
	private void deleteIndexWhenDelDir(DocDirectory docDirectory) {
		String path = docDirectory.getPath() + "/" + docDirectory.getId();
		List<DocFile> docFiles = getDocFiles(path);
		for (DocFile docFile : docFiles) {
			fileIndexService.deleteIndex(new DeleteIndexRunnable(new IndexFile(
					docFile.getId().toString())));
		}
	}

	/**
	 * 递归找出文件下的所有文件
	 * 
	 * @param path
	 * @return
	 */
	private List<DocFile> getDocFiles(String path) {
		List<DocDirectory> docDirectories = find(
				"select d from DocDirectory d where d.path like ?", path + "%");
		List<DocFile> docFiles = docFileService.find(
				"select f from DocFile f where f.path like ?", path + "%");
		for (DocDirectory docDir : docDirectories) {
			String subPath = docDir.getPath() + "/" + docDir.getId();
			docFiles.addAll(getDocFiles(subPath));
		}
		return docFiles;
	}

	/**
	 * 在删除文件夹时，更新删除文件夹所在的父文件夹的信息
	 * 
	 * @param docDirectory
	 */
	@SuppressWarnings("unused")
	private void updateDirectoryCountWhenDelDir(DocDirectory docDirectory) {
		if (docDirectory.getDirectoryId() != null
				&& docDirectory.getDirectoryId() > 0) {
			DocDirectory docDirectoryF = getById(docDirectory.getDirectoryId());
			int dirCount = docDirectoryF.getDirectoryCount() - 1;
			docDirectoryF.setDirectoryCount(dirCount > 0 ? dirCount : 0);
			update(docDirectoryF);
		}
	}

	/**
	 * 在删除文件夹时，更新删除文件夹所在的父文件夹或网盘的信息 且这个操作要是线程安全的，所以放到单线程中串行执行
	 * 
	 * @param docDirectory
	 */
	private void updateDirectoryWhenDelDir(DocDirectory docDirectory) {
		if (null != docDirectory.getDiskId() && docDirectory.getDiskId() > 0) {
			/*
			 * DocDisc docDisc =
			 * docDiscService.getById(docDirectory.getDiskId());
			 * docDisc.setDirectoryCount(null != docDisc.getDirectoryCount() ?
			 * docDisc .getDirectoryCount() - 1 : 0);
			 */
			fileIndexService.updateDisk(new UpdateDiskRunnable(docDirectory
					.getDiskId(), -docDirectory.getLarge(), 0, -1));
		} else {
			String[] pathIds = docDirectory.getPath().split("/");
			if (pathIds.length > 0) {
				fileIndexService.updateDisk(new UpdateDiskRunnable(Integer
						.parseInt(pathIds[0]), -docDirectory.getLarge()));
				for (int i = 1; i < pathIds.length; i++) {
					// DocDirectory docDir =
					// getById(Integer.parseInt(pathIds[i]));
					if (pathIds.length == i + 1) {
						/*
						 * docDir.setDirectoryCount(docDir.getDirectoryCount() -
						 * 1 > 0 ? (docDir .getDirectoryCount() - 1) : 0);
						 */
						fileIndexService.updateDirectory(new UpdateDirRunnable(
								Integer.parseInt(pathIds[i]), -1, 0,
								-docDirectory.getLarge()));
					} else {
						fileIndexService.updateDirectory(new UpdateDirRunnable(
								Integer.parseInt(pathIds[i]), docDirectory
										.getLarge()));
					}
					/*
					 * docDir.setLarge((docDir.getLarge() -
					 * docDirectory.getLarge() > 0) ? (docDir.getLarge() -
					 * docDirectory .getLarge()) : 0);
					 */
				}
			}
		}
	}

	@Override
	public List<DocDirectory> findHumanSeeableDir(int humanId, int directoryId) {
		humanId = (int) session.getAttribute(FinalConfig.SESSION_HUMANID);
		return null;
	}

	@Override
	public List<DocDirectory> findHumanSeeableDirInDisk(int diskId) {

		List<DocDirectory> directories = find(
				"select d from DocDirectory d where d.diskId=?", diskId);
		// int
		// unitTopId=tcunitService.getUnitTopId((int)session.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID));
		List<DocDirectory> list = new ArrayList<DocDirectory>();
		if (CastUtil.castBoolean(session.getAttribute(FinalConfig.is_admin))) {
			// 如果是管理员可以全部查看所有文件夹
			list.addAll(directories);
		} else {
			// 不是管理员就要根据文件夹的可见范围来展示
			for (DocDirectory docDirectory : directories) {
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_ALL))
					list.add(docDirectory);
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_UNIT)) {
					if (docDirectory.getUnitId() == (int) session
							.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID)) {
						list.add(docDirectory);
					}
				}
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_HUMANS)) {
					if (docDirectoryRangeService.canHumanSeeDir(docDirectory
							.getId(), (int) session
							.getAttribute(FinalConfig.SESSION_HUMANID)))
						list.add(docDirectory);
				}
			}
		}
		return list;
	}

	@Override
	public List<DocDirectory> findHUmanSeeableDirInDirectory(int directoryId) {
		List<DocDirectory> directories = find(
				"select d from DocDirectory d where d.directoryId=?",
				directoryId);
		// int
		// unitTopId=tcunitService.getUnitTopId((int)session.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID));
		List<DocDirectory> list = new ArrayList<DocDirectory>();
		if (CastUtil.castBoolean(session.getAttribute(FinalConfig.is_admin))) {
			// 如果是管理员可以全部查看所有文件
			list.addAll(directories);
		} else {
			for (DocDirectory docDirectory : directories) {
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_ALL))
					list.add(docDirectory);
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_UNIT)) {
					if (docDirectory.getUnitId() == (int) session
							.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID)) {
						list.add(docDirectory);
					}
				}
				if (docDirectory.getDisplayRange().equals(
						FinalConfig.DirectoryDisplayRange_HUMANS)) {
					if (docDirectoryRangeService.canHumanSeeDir(docDirectory
							.getId(), (int) session
							.getAttribute(FinalConfig.SESSION_HUMANID)))
						list.add(docDirectory);
				}
			}
		}
		return list;
	}

	@Override
	public String getUnIndexFile(int directoryId) {
		DocDirectory docDirectory = getById(directoryId);
		String path = GetRealPath.getPath(docDirectory.getPath()) + "/"
				+ docDirectory.getName();
		Searcher searcher = null;
		int unIndexFileCount = 0;
		int dirCount = 0;
		int indexFile = 0;
		try {
			FTPFile[] ftpFiles = FtpUtils.getDirectoryFiles(FinalConfig.getDocFtp(),
					path);
			searcher = new Searcher(FinalConfig.index_dir);
			for (FTPFile ftpFile : ftpFiles) {
				if (!ftpFile.isDirectory()) {
					TopDocs hits = searcher.TermQueryL("fileNameString",
							ftpFile.getName());
					if (hits.scoreDocs.length <= 0) {
						unIndexFileCount++;
					} else {
						indexFile++;
					}
				} else {
					dirCount++;
					int[] a = getDirFtpFile(path + "/" + ftpFile.getName(),
							searcher);
					indexFile += a[1];
					unIndexFileCount += a[0];
				}
			}
			put("unIndexFileCount", unIndexFileCount);
			put("dirCount", dirCount);
			put("indexFile", indexFile);
			searcher.close();
			putSuccess();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			putMessage("可能路径建立不对，无法读取到文件夹下的文件");
			putFalse();

		} finally {
			try {
				searcher.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return getMap();
	}

	@Override
	public String indexDirectory(int directoryId, int indexNd) {
		double sonDirLarge = indexDirectoryM(directoryId, indexNd);
		DocDirectory docDirectory = getById(directoryId);
		String[] pathIds = docDirectory.getPath().split("/");
		// 更新父路径上的文件夹信息
		for (int i = 0; i < pathIds.length; i++) {
			if (i == 0) {
				fileIndexService.updateDisk(new UpdateDiskRunnable(Integer
						.parseInt(pathIds[i]), sonDirLarge));
			} else {
				fileIndexService.updateDirectory(new UpdateDirRunnable(Integer
						.parseInt(pathIds[i]), sonDirLarge));
			}
		}
		return null;
	}

	/**
	 * 
	 * @param directoryId 需要建立索引的文件夹id
	 * @param indexNd 索引文件夹的年度
	 * @return
	 */
	private double indexDirectoryM(int directoryId, int indexNd) {
		DocDirectory docDirectory = getById(directoryId);
		String path = GetRealPath.getPath(docDirectory.getPath()) + "/"
				+ docDirectory.getName();
		String downLoadPath = FinalConfig.getFtpDownloadLocalPath("dir");
		String filePathId = docDirectory.getPath() + "/" + directoryId;
		Searcher searcher = null;
		double dirLarge = 0;
		int dirCount = 0;
		int fileCountInDirectory = 0;
		try {
			FTPFile[] ftpFiles = FtpUtils.getDirectoryFiles(FinalConfig.getDocFtp(),
					path);
			searcher = new Searcher(FinalConfig.index_dir);
			for (FTPFile ftpFile : ftpFiles) {
				if (!ftpFile.isDirectory()) {
					TopDocs hits = searcher.TermQueryL("fileNameString",
							ftpFile.getName());
					if (hits.scoreDocs.length <= 0) {
						FtpUtils.downloadFile(FinalConfig.docFtp,
								ftpFile.getName(), path, downLoadPath);
						String filePath = downLoadPath + ftpFile.getName();
						DocFile docFile = new DocFile();
						docFile.setFileName(ftpFile.getName());
						docFile.setLarge(getFileLarge(ftpFile.getSize()));
						docFile.setHumanId(Integer.parseInt(session
								.getAttribute(FinalConfig.SESSION_HUMANID)
								.toString()));
						docFile.setHumanName((String) session
								.getAttribute(FinalConfig.SESSION_HUMANNAME));
						docFile.setImgClass(fileIndexService
								.getImgClass(ftpFile.getName()));
						docFile.setDirectoryId(directoryId);
						docFile.setPath(filePathId);
						docFile.setDisplayFileName(ftpFile.getName());
						docFile.setCreateTime(new Timestamp(System
								.currentTimeMillis()));
						docFileService.save(docFile);
						IndexFile indexFile = new IndexFile(filePath,
								filePathId, docFile.getId().toString(),
								docFile.getHumanName(),
								ProjectUtils.timeStamp2String(docFile
										.getCreateTime()),
								docFile.getFileName(), docFile.getImgClass());
						indexFile.setNd(indexNd);
						// 设置搜索范围，初始化索引的文件默认都是全局可搜索
						indexFile
								.setSearchAble(FinalConfig.searchable_range_all);
						fileIndexService.index(new IndexRunnable(indexFile));
						dirLarge += docFile.getLarge();
						fileCountInDirectory++;
					} else {
					}
				} else {// FTPFILE是文件夹
					dirCount++;
					List<DocDirectory> docDirs = find(
							"select dir from DocDirectory dir where dir.name=? and dir.path=?",
							ftpFile.getName(), filePathId);
					if (docDirs.size() == 0) {
						DocDirectory docDir = new DocDirectory();
						docDir.setDirectoryCount(0);
						docDir.setFileCount(0);
						docDir.setHumanId((int) session
								.getAttribute(FinalConfig.SESSION_HUMANID));
						docDir.setLarge(0.0);
						docDir.setHumanName(session.getAttribute(
								FinalConfig.SESSION_HUMANNAME).toString());
						docDir.setUnitId(getUnitIdByDirectoryId(directoryId));
						docDir.setCreateTime(new Timestamp(System
								.currentTimeMillis()));
						docDir.setName(ftpFile.getName());
						docDir.setDirectoryId(directoryId);
						docDir.setPath(filePathId);
						docDir.setReName(ftpFile.getName());
						// docDir.setDisplayRange("1");
						docDir.setDisplayRange(FinalConfig.DirectoryDisplayRange_ALL);
						save(docDir);
						updateDirWhenAddDir(docDir);
						double sonDirLarge = indexDirectoryM(docDir.getId(),
								indexNd);
						dirLarge += sonDirLarge;
						docDir.setLarge(sonDirLarge);
						save(docDir);
					} else {
						indexDirectory(docDirs.get(0).getId(), indexNd);
					}
				}
			}
			docDirectory.setLarge(dirLarge + docDirectory.getLarge());
			docDirectory.setDirectoryCount(dirCount);
			docDirectory.setFileCount(fileCountInDirectory);
			save(docDirectory);
			// updateDirWhenAddDir(docDirectory);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return dirLarge;
	}

	/**
	 * 获取文件的大小
	 * 
	 * @param fileSize
	 * @return
	 */
	private double getFileLarge(Long fileSize) {
		DecimalFormat df = new DecimalFormat("######0.00");
		double s = fileSize / 1024;
		double size = Double.parseDouble(df
				.format((fileSize / 1024.00 / 1024.00)));
		return size;
	}

	/**
	 * 获取文件夹下还没有建立索引的文件数量
	 * 
	 * @param path
	 * @param searcher
	 * @return
	 * @throws Exception
	 */
	private int[] getDirFtpFile(String path, Searcher searcher)
			throws Exception {
		FTPFile[] ftpFiles = FtpUtils.getDirectoryFiles(FinalConfig.getDocFtp(),
				path);
		int[] count = new int[2];
		int unIndexFileCount = 0;
		int indexFileCount = 0;
		for (FTPFile ftpFile : ftpFiles) {
			if (ftpFile.isDirectory()) {
				int[] a = getDirFtpFile(path + "/" + ftpFile.getName(),
						searcher);
				unIndexFileCount += a[0];
				indexFileCount += a[1];
			} else {
				TopDocs hits = searcher.TermQueryL("fileNameString",
						ftpFile.getName());
				if (hits.scoreDocs.length <= 0) {
					unIndexFileCount++;
				} else {
					indexFileCount++;
				}
			}
		}
		count[0] = unIndexFileCount;
		count[1] = indexFileCount;
		return count;
	}

	@Override
	public List<DocDirectory> getPathDirectory(int directoryId) {
		DocDirectory docDirectory = getById(directoryId);
		String pathIds = docDirectory.getPath();
		String[] ids = pathIds.split("/");
		List<DocDirectory> docList = new ArrayList<>();
		for (int i = 1; i < ids.length; i++) {
			docList.add(getById(Integer.parseInt(ids[i])));
		}
		return docList;
	}

	@Override
	public String personalDirectory(int directoryId) {

		List<DocDirectory> docDirectories = find(
				"select dir from DocDirectory dir where dir.directoryId=?",
				directoryId);
		putSuccess();
		put("personalDirectories", docDirectories);
		if (docDirectories.size() == 0)
			putMessage("没有文件夹");
		return getMap();
	}

	@Override
	public void setPersonalDirId() {
		List<DocDirectory> dirs = find(
				"select dir from DocDirectory dir where dir.personalDisk=1 and dir.humanId=?",
				CastUtil.castInt(session
						.getAttribute(FinalConfig.SESSION_HUMANID)));
		if (dirs.size() != 0) {
			session.setAttribute(FinalConfig.PersonalDirId, dirs.get(0).getId());
		}
	}

	@Override
	public int getDirectoryDiskId(int directoryId) {
		DocDirectory docDirectory = getById(directoryId);
		String[] pathIds = docDirectory.getPath().split(FinalConfig.path_split);
		return CastUtil.castInt(pathIds[0]);
	}

	@Override
	public DocDisc getDisk(int docDirectoryId) {
		DocDirectory docDirectory = getById(docDirectoryId);
		String[] pathIds = docDirectory.getPath().split(FinalConfig.path_split);
		DocDisc docDisc = docDiscService.getById(CastUtil.castInt(pathIds[0]));
		return docDisc;
	}

	@Override
	public int getUnitIdByDirectoryId(int docDirectoryId) {
		DocDirectory docDirectory=getById(docDirectoryId);
		String[] pathIds=docDirectory.getPath().split(FinalConfig.path_split);
		if(pathIds.length>0){
			DocDisc docDisc=docDiscService.getById(CastUtil.castInt(pathIds[0]));
			return docDisc.getUnitId();
		}
		return CastUtil.castInt(session.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID));
	}

	@Override
	public DocDirectory createPersonalDirectory() {
		List<DocDirectory> dirs = find(
				"select dir from DocDirectory dir where dir.personalDisk=1 and dir.humanId=?",
				CastUtil.castInt(session
						.getAttribute(FinalConfig.SESSION_HUMANID)));
		if (dirs.size() != 0) {
			session.setAttribute(FinalConfig.PersonalDirId, dirs.get(0).getId());
			return dirs.get(0);
		}
		
		List<DocDisc> tempdocDiscs = docDiscService.find(
				"select disk from DocDisc disk where disk.unitId=?",
				CastUtil.castInt(session
						.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID)));
		// TODO 这里其实不用判断该部门的文件夹是否创建，因为一般情况下都是创建好的
		DocDisc docDisc = tempdocDiscs.get(0);
		DocDirectory personalDisk=new DocDirectory();
		personalDisk.setName(CastUtil.castString(session
				.getAttribute(FinalConfig.SESSION_HUMANNAME)));
		personalDisk.setDiskId(docDisc.getId());
		personalDisk.setHumanName(CastUtil.castString(session
				.getAttribute(FinalConfig.SESSION_HUMANNAME)));
		personalDisk.setPath(docDisc.getId().toString());
		personalDisk.setUnitId(CastUtil.castInt(session
				.getAttribute(FinalConfig.SESSION_HUMAN_UNIT_ID)));
		personalDisk.setReName(CastUtil.castString(session
				.getAttribute(FinalConfig.SESSION_HUMANNAME)));
		// 默认情况下，个人网盘的顶级文件夹可见范围是全局可见，然后再此后面的文件夹的可见性默认是个人可见的
		personalDisk.setDisplayRange(FinalConfig.DirectoryDisplayRange_ALL);
		personalDisk.setPersonalDisk(FinalConfig.PersonalDiskDir);
		//TODO  用于设置创建个人文件夹是通过，这里好像有个问题，就是自己调用方法是，拦截器，aop是无法拦截到的
		session.setAttribute(FinalConfig.canCreatDir, true);
		saveOrUpdateDirectory(personalDisk, null);
		session.setAttribute(FinalConfig.PersonalDirId, personalDisk.getId());
		return personalDisk;
	}

	@Override
	public List<DocDirectory> knowledgeDirectories() {
		
		List<DocDirectory> list=find("select dir from DocDirectory dir where dir.isKnowledge =1 and dir.directoryId=0");
		return list;
	}

	@Override
	public List<DocDirectory> knowledgeDirectoriesSub(int directoryId) {
		List<DocDirectory> list=find("select dir from DocDirectory dir where dir.directoryId=?",directoryId);
		return list;
	}
}
